import React from 'react';
import PropTypes from 'prop-types';
import * as Animatable from 'react-native-animatable';

export default class Animation extends React.Component {
  static propTypes = {
    enter: PropTypes.object,
    leave: PropTypes.object,
    showing: PropTypes.bool,
    style: PropTypes.any,
    shouldRender: PropTypes.bool,
  };

  static defaultProps = {
    enter: {
      animation: 'fadeIn',
      duration: 300,
      delay: 0,
    },
    leave: {
      animation: 'fadeOut',
      duration: 300,
      delay: 0,
    },
    shouldRender: true,
  };

  state = {
    display: 'none',
    render: this.props.showing,
  };

  handleViewRef = (ref) => (this.view = ref);

  onAnimationEnd = () => {
    this.props.onAnimationEnd && this.props.onAnimationEnd();
    !this.props.showing && this.setState({ display: 'none', render: false });
  };

  onAnimationBegin = () => {
    this.props.onAnimationBegin && this.props.onAnimationBegin();
    this.props.showing && this.setState({ display: 'flex', render: true });
  };

  UNSAFE_componentWillReceiveProps(nextProps) {
    if (nextProps.showing && !this.props.showing) {
      this.setState({
        render: true,
      });
    }
  }

  render() {
    const { enter, leave, showing, style, children, shouldRender, ...rest } = this.props;
    const { display, render } = this.state;
    return (
      ((!shouldRender && render) || shouldRender) && (
        <Animatable.View
          ref={this.handleViewRef}
          useNativeDriver
          style={[style, { display }]}
          onAnimationBegin={this.onAnimationBegin}
          onAnimationEnd={this.onAnimationEnd}
          animation={showing ? enter.animation : leave.animation}
          duration={showing ? enter.duration : leave.duration}
          iterationCount={1}
          iterationDelay={(showing ? enter.delay : leave.delay) || 0}
          {...rest}>
          {children}
        </Animatable.View>
      )
    );
  }
}
